#include<errno.h>
#include<fcntl.h>
#include<iostream>
#include"outputmemorystream.h"
#include<sys/mman.h>
#include<cstdio>
#include<cstring>

void outputmemorystream::create(const char* fileName)
{
	this->fd = open(fileName, O_CREAT | O_TRUNC | O_RDWR, S_IRWXU);
	if(this->fd == -1)
		std::cout << "Error opening stream: " << strerror( errno ) << std::endl;
}

void outputmemorystream:: close_s()
{
	if(this->wcount % BUFFER !=0)
		this->waddress[this->wcount++] = EOF;
	int ret = munmap(this->waddress, this->wcount*sizeof(int));
	this->waddress = 0;
	close(this->fd);
	if(ret < 0)
		std::cout << "Error closing stream: " << strerror( errno ) << std::endl;
}

void outputmemorystream::write_s(int data)
{
	if(this->wcount == 0)
	{
		lseek(this->fd, BUFFER*sizeof(int), SEEK_CUR);
		write(this->fd, "", 1);
		this->waddress = 0;
		if((this->waddress = (int*)mmap(0,BUFFER*sizeof(int), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0)) == MAP_FAILED)
	        	std::cout << "Error writing to stream: " << strerror( errno ) << std::endl;
		this->woffset = BUFFER*sizeof(int);
	}
	else if(this->wcount %BUFFER == 0 && this->wcount != 0)
	{
		munmap(this->waddress, BUFFER*sizeof(int));
		this->waddress = 0;
		lseek(this->fd, this->woffset + (BUFFER*sizeof(int)) , SEEK_SET);
		write(this->fd, "", 1);
		if((this->waddress = (int*)mmap(0,BUFFER*sizeof(int), PROT_READ|PROT_WRITE, MAP_SHARED, fd, this->woffset)) == MAP_FAILED)
	        	std::cout << "Error writing to stream: " << strerror( errno ) << std::endl;
		this->woffset += BUFFER*sizeof(int);
		this->wcount = 0;
	}
	this->waddress[this->wcount++] = data;
}
